/**/

#include "administrator.hpp"
#include "edge.hpp"
#include "node.hpp"

Administrator::Administrator()
{
}

Administrator::Administrator(std::string &fileToParseN, std::string &fileToParseE,
                                                         Logger *logger)
{
        this->create(fileToParseN,fileToParseE,logger);
}

void Administrator::create(std::string &fileToParseN, std::string &fileToParseE,Logger *logger)
{
        this->logger = logger;

        GraphFactory graphFactory(fileToParseN,fileToParseE,this->logger,&this->graph);

        graphFactory.generateGraph();
}


int Administrator::searchPath(std::string originRoadName, int originRoadHeight, std::string destinyRoadName, int destinyRoadHeight , int priority)
{
	Edge *edgeO = this->graph.getEdge(originRoadName,originRoadHeight);
	Edge *edgeD = this->graph.getEdge(destinyRoadName,destinyRoadHeight);
    if((edgeO)&&(edgeD))
    {
		int busqueda = searchPath(edgeO->getDestinyId(),edgeD->getOriginId(),priority);
		if (busqueda>0)
		{
			//Estos valores van a ser usados por el constructor graficador
			//Seteo que parte del edge pertenece al camino minimo.
			char buffer [33];
			char buffer2 [33];

			itoa(originRoadHeight,buffer,10);
			itoa(edgeO->getFinalHeight(),buffer2,10);


			roadPathFound = edgeO->getRoadName() + " "+ buffer + "-" + buffer2 + "-> "+roadPathFound;


			itoa(edgeD->getInitialHeight(),buffer,10);
			itoa(destinyRoadHeight,buffer2,10);

			roadPathFound = roadPathFound + edgeD->getRoadName()+ " "+ buffer + "-" + buffer2;


			edgeO->setBelongToMP(originRoadHeight,edgeO->getFinalHeight());
			edgeD->setBelongToMP(edgeD->getInitialHeight(),destinyRoadHeight);
		}
		return busqueda;
	}
    else
    {
            std::string detail = "Edge ";
			if (!edgeO)
            {
                    detail += "origen inexistente";
                    this->errorCode=11;
            }
            else
            {
                    detail += "destino inexistente";
                    this->errorCode=21;
            }
            this->logger->reportErrorMessage("SearchAlgorithm","execute",detail);

            return -1;

    }

}


int Administrator::searchPath(std::string originId, std::string destinyId, int priority)
{
        Node *nodeO = this->graph.getNode(originId);
        Node *nodeD = this->graph.getNode(destinyId);
        if((nodeO)&&(nodeD))
        {

                SearchAlgorithm searchAlgorithm(this->logger);
                std::string path;
				std::string roadPath;
                if(searchAlgorithm.execute(&this->graph,nodeO,nodeD,priority)>=0)
                {
                        Node *destiny = this->graph.getNode(destinyId);


                        Edge *previous = destiny->getMinimunPathEdge();
						



                        path="Nodo "+destinyId;

						destiny->setBelongToMP();

                        while(previous != NULL)
                        {       

							char buffer [33];
							char buffer2 [33];
							std::string prevOriginId = previous->getOriginId();
                            std::string prevId = previous->getId();

                            path="Nodo "+prevOriginId+" -> Arista "+ prevId +" -> "+path;
							
							itoa(previous->getInitialHeight(),buffer,10);
							itoa(previous->getFinalHeight(),buffer2,10);
						

							roadPath= previous->getRoadName() + " "+ buffer + "-" + buffer2 + "-> "+roadPath;
							
							//Arista previa si de camino minimo en su completitud
							previous->setBelongToMP();

                            destiny = this->graph.getNode(prevOriginId);

							//Nodo destino pertence al MP
							destiny->setBelongToMP();

                            previous = destiny->getMinimunPathEdge();
                        }
                        this->pathFound=path;
						this->roadPathFound = roadPath;
                        return 1;
                }
                else
                {
                        return 0;
                }
        }
        else
        {
                std::string detail = "Nodo ";
                if (!nodeO)
                {
                        detail += "origen inexistente";
                        this->errorCode=10;
                }
                else
                {
                        detail += "destino inexistente";
                        this->errorCode=20;
                }
                this->logger->reportErrorMessage("SearchAlgorithm","execute",detail);

                return -1;

        }

}

bool Administrator::isGraphCreated(){
    if (this->graph.getNumberOfNodes() > 0)
        return true;
    return false;
}

void Administrator::cleanBestPathValues()
{
        this->graph.cleanBestPathValues();
}

string Administrator::getPath()
{
        return this->pathFound;
}

string Administrator::getRoadPath()
{
        return this->roadPathFound;
}


int Administrator::getErrorCode()
{
        return this->errorCode;
}

Graph *Administrator::getGraph(){
    return &(this->graph);
}


Administrator::~Administrator(){}
